#include "tcp_server.h"

namespace eGear{


TcpServer::TcpServer(char *_addr, int _port, int _backlog){
	socketfd = -1;
	int addrlen = strlen(_addr)+1;
	addr = new char[addrlen];
	max_addr_len=addrlen;
	strcpy(addr, _addr);
	port = _port;
	backlog = _backlog;
};

TcpServer::~TcpServer(){
	if(addr!=NULL){
		delete addr;
		addr = NULL;
	};
	if(socketfd != -1){
		close(socketfd);
		socketfd = -1;
	};
};

int TcpServer::startUp(){
	if(socketfd!=-1) {
		// already a socket created
		close(socketfd);
		socketfd = -1;
	}
	socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if(socketfd ==-1){
		perror("socket failed to create");
		return -1;
	}
	struct sockaddr_in server_addr;
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	if(int(server_addr.sin_addr.s_addr=inet_addr(addr))==-1){
		perror("bad address format");
		return -1;
	}
	server_addr.sin_port = htons(port);
	if(bind(socketfd, (struct sockaddr *) &server_addr,
			sizeof(struct sockaddr_in)) ==-1){
		perror("socket failed to bind");
		return -1;
	}
	if(listen(socketfd, backlog) ==-1){
		perror("socket failed to listen");
		return -1;
	};
};

int TcpServer::shutDown(){
	if(socketfd==-1){
		return 0;
	}
	int result;

	if((result = close(socketfd))!=-1){
		socketfd = -1;
	}
	else{
		perror("error to close the socket");
	}
	return result;
};

TcpConnection *TcpServer::getNewClient(){
	struct sockaddr_in client_addr;
	socklen_t addrlen;
	int client_socket;
	if((client_socket=accept(socketfd,
			(sockaddr*) &client_addr, &addrlen))<0){
		perror("socket failed in accept");
		return NULL;
	};
	return new TcpConnection(client_socket,
			(sockaddr*) &client_addr, addrlen);
};

int TcpServer::setAddr(char *_addr){
	int new_addr_len = strlen(_addr)+1;
	if(max_addr_len < new_addr_len){
		delete addr;
		addr = new char[new_addr_len];
		if(addr==NULL) {
			perror("no memory");
			return -1;
		}
		max_addr_len = new_addr_len;
	}
	strcpy(addr, _addr);
	return 0;
};

};

// TODO
